home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 015 / printcom.arc / PRINTCOM.INF
Encoding:
Text File  |  1986-11-02  |  11.3 KB  |  272 lines

  1. Date: Sun, 25 Aug 85 23:02:37 edt
  2. From: jcm@ornl-msr.ARPA (James A. Mullens)
  3. To: info-ibmpc@usc-isib.ARPA
  4. Subject: PRINT.COM 3.1 Internals
  5.  
  6.  
  7. I offer the following description of the internals of PRINT.COM for
  8. DOS 3.1 as a guide for those wishing to implement background tasks
  9. under DOS 3.1.  This is the non-networked version of PRINT.COM.
  10.  
  11. This information is a good starting point for serious hackers,
  12. determined to implement their own background task or collapse over the
  13. keyboard trying.  I won't bore you with all of the reasons you should
  14. not write such a background task -- just let me say that if you do, be
  15. prepared to assume full responsibility for your actions and the actions
  16. of your program!
  17.  
  18. I am giving this to the public domain mostly because I think some people
  19. might have some fun trying to use this stuff, and because I hope some
  20. public domain programs will turn up.  This little project required
  21. the interpretation of 47 pages of uncommented assembly language, which
  22. relocates itself, uses 3 different CSs, and has innumerable subroutines.
  23. I doubt that I am the first to do this, but I appear to be the first to
  24. offer my findings to the net.
  25.  
  26. The description is only partially complete.  I tried to concentrate on
  27. the parts of PRINT.COM related to the problem of calling DOS functions.
  28. I cannot say that all you need to know is here because I have not
  29. tried to write a background program that calls DOS.  Even if I had an
  30. (apparently) working background program, I would hesitate to say that
  31. it didn't have a bug which would rear its ugly head in the future.
  32.  
  33. I look forward to exchanging notes with anyone else who takes an
  34. interest!  If you do something in the near future, please send a
  35. message to me directly (in addition to the network) so that I won't
  36. be attempting to do something you have already done.
  37.  
  38.  
  39.                DESCRIPTION OF DOS 3.1 PRINT.COM INTERNALS
  40.                      James A Mullens / jcm@ornl-msr
  41.                             August 1985
  42.  
  43.      First Stage Setup
  44.  
  45.     Compute stack address and entry point for second stage of setup.
  46.     Adjust some values pointed to by a table.
  47.     Relocate most of program, moving down 310 bytes.
  48.     JMP FAR to second stage setup, changing CS:IP.
  49.  
  50.      Second Stage Setup
  51.  
  52.     Check DOS version.
  53.     Free Allocated Memory.
  54.     Save pointers to old INTs 28,2F,13,15,17,14,05, and 1C if
  55.       spooler is not installed already.
  56.     If spooler already installed, but OK to reinstall, do so.
  57.       If not OK to reinstall do something (?) which may result
  58.       in task terminate with result code FF.
  59.     Do INT 37 (DOS internal). Reason for doing?
  60.     Scan command line, possibly adding filename passed to spool
  61.       queue.  Operations done here may result in closing of
  62.       file handles 0 - 5 and terminate with result code 0.
  63.     Many operations involving byte memory comparisons and
  64.       subroutine calls...
  65.       Get current disk (DOS func 19). (Label L15FF)
  66.       Get current directory (DOS func 47). (Label L1627)
  67.       Get extended error (DOS func 59). (Label L1730)
  68.       Skip remainder of setup if PRINT is already installed.
  69.         Simply submit new file for spooling.
  70.     Ask for name of device to spool to.
  71.  
  72.      Third Stage Setup - installation of memory resident portion.
  73.  
  74.     Find DOS driver for output device.
  75.       This involves DOS func 52, perhaps to find a pointer to the
  76.       device driver list.  Reject any block-structured device
  77.       as an output device.
  78.     INT redirection.  Save and reset vectors for INTs 28,13,15,
  79.       17,14, and 05.
  80.     DOS function 34 to get location of the INDOS flag in ES:BX.
  81.       The INDOS flag is not used in the same way as DOS v2.0
  82.       used it.
  83.     Save old INT 1C handler address.
  84.     Get print spooler installed state.  If not installed, install
  85.       new INT 1C handler.  If spooler already installed,
  86.       test a flag to determine if should not install new
  87.       INT 1C handler.
  88.     Install new INT 1C handler if necessary.
  89.     Print 'resident part of print installed'.
  90.     Far jump to address stored at CS:[0E73H].  I assume this exits.
  91.  
  92.      Timer (INT 1C) actions
  93.  
  94.     (Hex numbers refer to memory locations).
  95.  
  96.     Do an INT 2A and exit if carry set.  This is an undocumented
  97.       INT, but interesting.  It seems one is obliged to do
  98.       INT 2A before exiting interrupt if this call was successful.
  99.       This may be a simple guard against re-entering this 1C
  100.       handler.
  101.     Increment 2D7 and 2D8.  Used in the print action routine.
  102.     If 2D9 is not 0, decrement it and
  103.       exit after calling INT 2A.  (2D9 is a tick countdown 'timer'.
  104.       Print actions are done only when it counts down to 0).
  105.     If 2CC is not 0, exit without doing INT 2A, else read 8259
  106.       interrupt status register.  Exit after doing INT 2A if
  107.       any interrupts except the timer are active.
  108.       2CC is also increment/decremented in the INT 28 handler and
  109.       the ROM BIOS INT 13 handler (note bene).
  110.     Check INDOS flag byte and the byte _before_ it.  If any bits
  111.       are set, exit after doing INT 2A.
  112.     Increment 2CC (flag that print actions are being done).
  113.     Zero 2D7 and 2D8.
  114.     Enable interrupts.
  115.     Test byte flag 2D5.  If any bits set, do not send EOI to
  116.       8259.  This flag appears to be used to communicate with the
  117.       INT 2F handler.  Possibly the INT 2F handler can invoke
  118.       this INT 1C handler, in which case hardware interrupt stuff
  119.       should not be done.
  120.     Do any print actions needed (including write, read, open a
  121.       new spool file, print error messages, etc.).
  122.     Disable interrupts.
  123.     Move 2DA to 2D9.  (Reset countdown timer).
  124.     Decrement 2CC.  (Flag that print actions are over).
  125.     Do INT 2A.
  126.     If 2D5 has no bits set call old INT 1C handler, otherwise
  127.       exit via IRET.
  128.  
  129.      INT 2F (new handler inserted by PRINT)
  130.  
  131.     This handler is documented in the DOS manual.
  132.  
  133.      INT 28 Actions (new handler inserted by PRINT)
  134.  
  135.     INT 28 is undocumented, 'used internally by DOS'.  This INT
  136.     will also cause print actions to do done under certain
  137.     conditions.  It is believed that INT 28 calls are made by the
  138.     DOS 'get from keyboard' routines whenever it is safe to do
  139.     file i/o.  (See the net's archive file documenting DOS
  140.     functions and interrupts.)  Notice that no attempt is made
  141.     to examine the 'INDOS' flag.
  142.  
  143.     Call INT 2A.  If carry set, exit immediately.
  144.     If 2CC is not 0, exit after calling INT 2A.
  145.     Increment 2CC and 2D6.
  146.     Disable INTs.
  147.     Do Print actions (identical to INT 1C handler actions).
  148.     Zero 2D6, move 2DA to 2D9 (byte), decrement 2CC.
  149.     Do INT 2A and continue with old INT 28 handler.
  150.  
  151.      Print Actions called by INT 1C and INT 28 handlers
  152.  
  153.     This is a very elaborate piece of code.  A queue of files
  154.     to print is maintained.   Files are opened and closed.
  155.     Errors are handled.  Etc, etc.  I assume most people will
  156.     not be interested in how the file spooling is done.
  157.  
  158.     The extended file management group of DOS functions are
  159.     used for file i/o.
  160.  
  161.     In the print action routine, DOS functions 50 and 51
  162.     are used whenever file i/o is done.  Some condition is indicated
  163.     by a flag of 0 or 1.  The print action routine and INT 2F
  164.     handler explicitly switch to state 0 before terminating.
  165.     This is done by moving a word to BX and calling DOS function
  166.     50.  Whenever file i/o is to take place, the state is switched
  167.     to 1.  This is done by calling DOS
  168.     function 51, saving a result in BX to the word used above,
  169.     moving a new word into BX, and calling DOS function 50.
  170.  
  171.     I have 2 clues as to what DOS functions 50 and 51 do.  One
  172.     source says DTA stuff for DOS 2.x, another source says
  173.     PSP stuff for DOS 3.x.  (The net's archive file documenting
  174.     DOS functions says with assurance that 50 sets a PSP address
  175.     and 51 gets the current PSP address.  This seems to be so.)
  176.     If these are PSP actions, then state 1 has the PSP set to its
  177.     original value (on PRINT.COM entry), and this is the state
  178.     set when doing file i/o.  I do not know why it is changed
  179.     when print actions are over.
  180.  
  181.     DOS function 5D is called just prior to exiting the print
  182.     actions routine.
  183.  
  184.     See the discussion of the INT 15 handler below for a special
  185.     case of control-break handling when doing DOS function calls.
  186.  
  187.     Special character handling:
  188.     Backspace erases the previous character.
  189.     Non-printing control characters are filtered.
  190.     Tabs are expanded and all of the spaces sent
  191.     immediately to the output device -- the code seems to have the
  192.     philosophy that all output resulting from the current input
  193.     character must be done in the current call of the INT 1C
  194.     handler.
  195.  
  196.     Output is done by calling device driver 'strategy' and
  197.     'interrupt' routines.  (A device 'interrupt' routine has
  198.     nothing to do with machine interrupts -- it only performs
  199.     the actions indicated by the strategy call.)
  200.     The device state is checked prior to write commands to see if
  201.     the device is busy or has an error.  PRINT will attempt to
  202.     get a 'ready' state 20,000 times before giving up.
  203.  
  204.      New ROM BIOS interrupt handlers.
  205.  
  206.     Disk handler (INT 13)
  207.         Increment 2CC on entry, decrement 2CC on exit.
  208.         This flag is checked and used by INT 1C handler and
  209.         INT 28 handler also.
  210.     Cassette and other device handler (INT 15)
  211.         The calls expected by the new handler do not conform
  212.         to IBM PC ROM BIOS cassette tape handler.
  213.         I notice that the AT supports a variety of device
  214.         calls through this vector, but I haven't seen a
  215.         documented call for the function this new INT 15
  216.         handler intercepts (AH = 20).
  217.  
  218.         The new handler would pass all 'old cassette' calls
  219.         to ROM BIOS.  Any call with AH = 20 would be
  220.         intercepted.  If AL > 1, go to the old handler.
  221.         (On the old cassette handler, AH > 1 meant do a
  222.         read/write).  If AL = 1, zero flag CBB and return.
  223.         (On the old cassette handler, AH = 1 meant turn the
  224.         motor off). If AL > 1, increment CBB and move the
  225.         passed ES:BX to CBC, and return.
  226.         When the Print Action routine does file i/o, it goes
  227.         to great pains to disable control-break recognition
  228.         whenever flag CBB is set.  When CBB is set, the file
  229.         i/o routine increments the byte pointed to by CBC,
  230.         then does the i/o, and then decrements the byte.
  231.     Printer handler (INT 17)
  232.         Reject all calls for printer unit which is the output
  233.         device.  (Use flag 2CC to determine if call is from
  234.         PRINT code.
  235.     Serial Port handler (INT 14)
  236.         Similar to printer handler.
  237.     Print Screen handler (INT 05)
  238.         Reject call unless not spooling to printer 0.
  239.  
  240.      SUMMARY
  241.  
  242.     Run the background task off timer (1C) interrupts.
  243.  
  244.     You may be required to implement an INT 28 handler if
  245.     it is necessary to perform file operations while the
  246.     foreground is waiting on keyboard input.
  247.  
  248.     You may be required to issue INT 2A on entry, and exit
  249.     immediately if returns with carry set.  If carry is not set
  250.     you must also call INT 2A before exiting your interrupt
  251.     routine.
  252.  
  253.     Intercept ROM BIOS calls to reject any calls on the device
  254.     being used by the background job.
  255.  
  256.     Do not attempt to execute while the foreground
  257.     job has called the ROM BIOS disk (INT 13) functions.
  258.  
  259.     Do not attempt to execute if INDOS byte or the byte before it
  260.     have any bits set.
  261.  
  262.     Do not attempt to execute if any other hardware interrupts
  263.     are being processed.
  264.  
  265.     It is possible to do normal DOS file handling calls, but
  266.     it may be necessary to perform additional actions similar to
  267.     (undocmented) DOS functions 50 and 51.  A call to DOS function
  268.     5D may also be necessary after all file stuff is finished.
  269.  
  270.  
  271. Enjoy!!
  272.